package jast.util;

import java.util.HashMap;
import java.util.Map;

public class CompanySocialUtil {

    private static final int[] orgCodeWeight = {3, 7, 9, 10, 5, 8, 4, 2};

    private static final int[] socialIdWeight = {1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28};

    private static final Map<String, Integer> socialIdIndex = new HashMap<String, Integer>();

    private static final String[] socialBasic = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
            "A", "B", "C", "D", "E", "F", "G", "H", "J", "K",
            "L", "M", "N", "P", "Q", "R", "T", "U", "W", "X", "Y"};

    static {
        for (int i = 0; i < socialBasic.length; i++) {
            socialIdIndex.put(socialBasic[i], i);
        }
    }

    /**
     * 校验统一社会信用代码
     * @param str 统一社会信用代码
     * @return true 校验通过，else false
     */
    public static boolean checkCompanySocialId(String str) {
        if (str == null || str.length() != 18) {
            return false;
        }
        return str.equals(createCompanySocialId(str));
    }

    /**
     * 生成统一社会信用代码
     * @param str 至少统一社会信用代码前16位
     * @return 18位统一社会信用代码  if str足16位且符合规则, else 空字符串
     */
    public static String createCompanySocialId(String str) {
        if (str == null || str.length() < 16) {
            return "";
        }
        String socialCode = str.substring(0, 16);
        if (!socialCode.matches("^(?:11|12|13|19|51|52|53|59|91|92|93|Y1)\\d{6}[\\dA-Z^IOZSV]{8}$")) {
            return "";
        }
        String orgCode = socialCode.substring(8, 16);
        int orgCheckCode = 0;
        String orgCheckCodeStr = "";
        for (int i = 0, len = orgCode.length(); i < len; i++) {
            orgCheckCode += Integer.parseInt(orgCode.substring(i, i + 1), 36) * orgCodeWeight[i];
        }
        orgCheckCode = 11 - orgCheckCode % 11;
        if (orgCheckCode == 11) {
            orgCheckCodeStr = "0";
        } else if (orgCheckCode == 10) {
            orgCheckCodeStr = "X";
        } else {
            orgCheckCodeStr = orgCheckCode + "";
        }
        socialCode += orgCheckCodeStr;

        int socialCheckCode = 0;
        for (int i = 0, len = socialCode.length(); i < len; i++) {
            socialCheckCode += socialIdIndex.get(socialCode.substring(i, i + 1)) * socialIdWeight[i];
        }
        socialCheckCode = 31 - socialCheckCode % 31;
        String socialCheckCodeStr = socialBasic[socialCheckCode % 31];
        socialCode += socialCheckCodeStr;
        return socialCode;
    }

}
